package com.white.framework.flow.utils;

import com.white.framework.flow.FlowNodeJob;
import com.white.framework.flow.enums.FlowNodeType;
import com.white.framework.flow.enums.FlowOptionEnum;
import com.white.framework.flow.exception.FlowNodeJobBusinessException;
import com.white.framework.flow.utils.SpringUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 流程节点执行工具类
 * 主入口
 * @author white
 * @create 2020-11-30 16:54
 */
@Slf4j
public class FlowNodeJobUtils {

    private FlowNodeJobUtils(){}

    /**
     * 根据节点获取该节点需要执行的方法
     *
     * @param flowNodeType 流程节点
     * @return 节点Job
     */
    private static <D,R> FlowNodeJob<D,R> getJob(FlowNodeType flowNodeType){
        try {
            FlowNodeJob<D,R> bean = SpringUtil.getBean(flowNodeType.getJobClass());
            return bean;
        } catch (Exception e) {
            log.error("获取节点Job实例化对象时出错，节点: [{}] , 没有指定实现类",flowNodeType.getNodeName(),e);
            throw new FlowNodeJobBusinessException("获取节点Job实例化对象时出错");
        }
    }

    /**
     * 全自动执行
     * 完整的执行这个Job
     * 他包含了这个Job的所有生命周期的处理
     *
     * @param businessNo 业务单号
     */
    public static <D,R> R fullyAutomaticRun(FlowNodeType flowNodeType, String businessNo , D businessDTO){
        return (R) getJob(flowNodeType).fullyAutomaticRun(businessNo,businessDTO);
    }

    /**
     * 半自动执行
     *
     * 他会跳过执行器阶段,直接执行结果
     * 因为执行器阶段已由人工完成
     *
     * @param option 操作结果
     * @param businessNo 业务单号
     * @param operatorId 操作员ID
     * @param operatorName 操作员名称
     * @param remarks 备注
     */
    public static <R> R semiAutomaticRun(FlowNodeType flowNodeType, FlowOptionEnum option , String businessNo , String operatorId , String operatorName, String remarks){
        return (R) getJob(flowNodeType).semiAutomaticRun(option,businessNo,operatorId,operatorName,remarks);
    }
}
